<template>
  <el-dialog 
    v-model="visible" 
    title="商业问答（Beta）" 
    width="1200px" 
    :close-on-click-modal="false" 
    append-to-body 
    :z-index="3000"
    class="bi-modal-dialog"
    :modal="true"
    :center="false"
    custom-class="bi-modal-custom"
    style="margin-top: 2vh !important;"
  >
    <div class="bi-modal-content">
      <!-- 聊天对话区域 -->
      <div class="chat-container">
        <div class="chat-header">
          <h2>数据分析助手</h2>
          <p>输入你的业务问题，AI将为你分析数据并生成洞察</p>
        </div>
        
        <!-- 消息列表 -->
        <div class="messages-area" ref="messagesContainer">
          <div v-if="messages.length === 0" class="empty-state">
            <div class="empty-icon">🤖</div>
            <div class="empty-text">开始你的数据分析对话吧！</div>
            <div class="empty-example">例如：最近7天各分类新闻数量</div>
          </div>
          
          <div class="messages-list">
            <div
              v-for="(message, index) in messages"
              :key="index"
              class="message"
            >
              <!-- 用户消息 -->
              <div v-if="message.type === 'user'" class="message-content user-message">
                <div class="message-bubble user-bubble">
                  {{ message.content }}
                </div>
                <div class="message-avatar user-avatar">👤</div>
              </div>
              
              <!-- AI消息 -->
              <div v-else class="message-content ai-message">
                <div class="message-avatar ai-avatar">🤖</div>
                <div class="message-bubble ai-bubble">
                  <div v-if="message.loading" class="loading-dots">...</div>
                  <div v-else-if="message.content" class="message-text">
                    {{ message.content }}
                  </div>
                  
                  <!-- 图表等待区域 -->
                  <div v-if="message.chartWaiting" class="chart-waiting">
                    <div class="waiting-icon">📊</div>
                    <div class="waiting-text">等待图表数据完整...</div>
                  </div>
                  
                  <!-- 图表区域 - 作为AI消息的一部分 -->
                  <div v-if="message.chartConfig" class="chart-area">
                    <div class="chart-header">
                      <h4>{{ message.chartConfig.type === 'skipped' ? '图表状态' : '图表展示' }}</h4>
                      <div class="chart-status">
                        <span v-if="message.chartWaiting" class="status-waiting">等待图表数据...</span>
                        <span v-if="message.chartConfig.type === 'skipped'" class="status-skipped">图表生成被跳过</span>
                        <span v-else class="status-ready">图表数据就绪</span>
                      </div>
                    </div>
                    
                    <div v-if="message.chartConfig.type !== 'skipped'" class="chart-container">
                      <div :id="`chart_${index}`" class="chart-renderer"></div>
                    </div>
                    
                    <div v-if="message.chartConfig.type !== 'skipped'" class="chart-raw-data">
                      <details>
                        <summary>图表配置详情</summary>
                        <pre>{{ JSON.stringify(message.chartConfig, null, 2) }}</pre>
                      </details>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 进度区域 -->
          <div v-if="sending && progressInfo.length > 0" class="progress-area">
            <div class="progress-bubble">
              <div class="progress-title">处理进度</div>
              <div class="progress-list">
                <div
                  v-for="(item, index) in progressInfo"
                  :key="index"
                  class="progress-item"
                >
                  <span class="progress-icon">⏳</span>
                  <span class="progress-text">{{ item }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 输入区域 -->
      <div class="input-area">
        <div class="input-container">
          <el-input
            v-model="question"
            type="textarea"
            :rows="3"
            placeholder="请输入你的业务问题，如：最近7天各分类新闻数量"
            @keydown.enter.exact.prevent="send"
            :disabled="sending"
          />
          
          <div class="input-controls">
            <div class="input-options">
              <el-select v-model="timeRange" placeholder="时间范围" size="small">
                <el-option label="最近7天" value="week" />
                <el-option label="最近30天" value="month" />
                <el-option label="今天" value="today" />
                <el-option label="昨天" value="yesterday" />
                <el-option label="最近一年" value="year" />
              </el-select>
              
              <el-select v-model="chartType" placeholder="图表类型" size="small">
                <el-option label="自动判断" value="auto" />
                <el-option label="柱状图" value="bar" />
                <el-option label="折线图" value="line" />
                <el-option label="饼图" value="pie" />
                <el-option label="表格" value="table" />
              </el-select>
              
              <el-input-number 
                v-model="maxRecords" 
                :min="10" 
                :max="1000" 
                size="small"
                placeholder="最大记录数"
              />
            </div>
            
            <div class="input-actions">
              <span class="input-help-text">Enter 发送 · Shift+Enter 换行</span>
              <el-button v-if="sessionId" type="warning" size="small" @click="clearSession">
                清空会话
              </el-button>
              <el-button type="primary" :loading="sending" @click="send">
                {{ sending ? '发送中...' : '发送' }}
              </el-button>
            </div>
          </div>
          
          <div class="input-help">
            <span v-if="sessionId" class="session-info">会话: {{ sessionId.substring(0, 20) }}...</span>
          </div>
          
          <el-alert v-if="error" type="error" :title="error" show-icon />
        </div>
      </div>
    </div>
    
    <!-- 去掉footer，让输入框相关组件统一下移 -->
  </el-dialog>
</template>

<script setup>
import { ref, computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
import * as echarts from 'echarts'

const props = defineProps({
  modelValue: { type: Boolean, default: false },
  testConversations: { type: Array, default: () => [] }
})
const emit = defineEmits(['update:modelValue', 'test-event'])

const visible = computed({
  get: () => props.modelValue,
  set: (v) => emit('update:modelValue', v)
})

const question = ref('')
const timeRange = ref('week')
const chartType = ref('auto')
const maxRecords = ref(100)
const includeSql = ref(false)
const includeSummary = ref(true)
const sessionId = ref('')
const error = ref('')

// 聊天相关状态
const messages = ref([])
const sending = ref(false)
const streamData = ref([])
const progressInfo = ref([])
const conversationComplete = ref(false)

// 图表相关
const chartRef = ref(null)
let chartInstance = null

// 消息容器引用
const messagesContainer = ref(null)

const close = () => { visible.value = false }

// 滚动到最新消息
const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    }
  })
}

// 生成新的会话ID
const generateSessionId = () => {
  sessionId.value = 'bi-session-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9)
}

// 清空会话
const clearSession = async () => {
  if (sessionId.value) {
    try {
      await fetch(`http://localhost:8080/api/ai/bi/session/${sessionId.value}`, {
        method: 'DELETE'
      })
      sessionId.value = ''
      messages.value = []
      console.log('会话已清空')
    } catch (e) {
      console.error('清空会话失败:', e)
    }
  }
}

// 清理状态函数
const clearStates = () => {
  streamData.value = []
  progressInfo.value = []
  conversationComplete.value = false
  
  // 清理之前的图表实例，准备重新渲染
  if (chartInstance) {
    console.log('清理之前的图表实例')
    chartInstance.dispose()
    chartInstance = null
  }
}

// 更新进度信息
const updateProgress = (eventType) => {
  let progressText = ''
  
  switch (eventType) {
    case 'start':
      progressText = '开始处理查询...'
      break
    case 'sql_generation':
      progressText = '正在生成SQL查询...'
      break
    case 'sql_llm':
      progressText = '使用AI生成SQL...'
      break
    case 'sql_generated':
      progressText = 'SQL生成完成'
      break
    case 'sql_optimized':
      progressText = 'SQL已优化'
      break
    case 'query_execution':
      progressText = '正在执行数据库查询...'
      break
    case 'query_completed':
      progressText = '查询完成'
      break
    case 'data_ready':
      progressText = '数据准备就绪'
      break
    case 'chart_generation':
      progressText = '正在生成图表配置...'
      break
    case 'summary_generation':
      progressText = '正在生成数据洞察...'
      break
    default:
      progressText = `处理中: ${eventType}`
  }
  
  if (progressText) {
    progressInfo.value.push(progressText)
    nextTick(() => {
      const progressList = document.querySelector('.progress-list')
      if (progressList) {
        progressList.scrollTop = progressList.scrollHeight
      }
    })
  }
}

// 为特定消息渲染图表
const renderChartForMessage = (config, messageIndex) => {
  console.log(`为消息 ${messageIndex} 渲染图表，配置:`, config)
  
  nextTick(() => {
    const chartContainer = document.getElementById(`chart_${messageIndex}`)
    if (!chartContainer) {
      console.error(`找不到消息 ${messageIndex} 的图表容器`)
      return
    }
    
    try {
      // 检查容器尺寸
      const rect = chartContainer.getBoundingClientRect()
      console.log(`消息 ${messageIndex} 图表容器尺寸:`, rect.width, 'x', rect.height)
      
      if (rect.width > 0 && rect.height > 0) {
        const chartInstance = echarts.init(chartContainer)
        const option = generateChartOption(config)
        console.log('生成的ECharts配置:', option)
        
        chartInstance.setOption(option, true)
        console.log(`消息 ${messageIndex} 的图表渲染成功`)
      } else {
        console.log(`消息 ${messageIndex} 图表容器尺寸为0，等待DOM更新`)
        setTimeout(() => {
          renderChartForMessage(config, messageIndex)
        }, 100)
      }
    } catch (error) {
      console.error(`消息 ${messageIndex} 的图表渲染失败:`, error)
    }
  })
}

// 生成ECharts配置
const generateChartOption = (config) => {
  console.log('生成图表配置:', config)
  
  if (config.type === 'skipped') {
    // 处理跳过的图表
    return {
      title: {
        text: config.title || '图表生成被跳过',
        left: 'center',
        top: '20%',
        textStyle: {
          color: '#666',
          fontSize: 16
        }
      },
      graphic: [
        {
          type: 'text',
          left: 'center',
          top: '45%',
          style: {
            text: config.reason || '此问题类型无需图表展示',
            fontSize: 14,
            color: '#999',
            textAlign: 'center'
          }
        },
        {
          type: 'text',
          left: 'center',
          top: '60%',
          style: {
            text: `问题类型: ${config.questionType || '未知'}`,
            fontSize: 12,
            color: '#BBB',
            textAlign: 'center'
          }
        }
      ]
    }
  }
  
  const baseOption = {
    title: {
      text: config.title || '数据图表',
      left: 'center',
      textStyle: {
        color: '#333',
        fontSize: 16
      }
    },
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      left: '10%',
      right: '10%',
      bottom: '15%',
      top: '20%'
    }
  }

  // 处理后端发送的图表配置格式
  if (config.xAxis && config.yAxis && config.series) {
    // 后端格式：直接使用xAxis和yAxis数组
    return {
      ...baseOption,
      xAxis: {
        type: 'category',
        data: config.xAxis
      },
      yAxis: {
        type: 'value'
      },
      series: config.series.map(series => ({
        ...series,
        itemStyle: {
          color: series.type === 'bar' ? '#007AFF' : '#34C759'
        }
      }))
    }
  }

  // 处理前端测试格式
  switch (config.type) {
    case 'bar':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          data: config.data?.map(item => item[config.xAxis]) || []
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'bar',
          data: config.data?.map(item => item[config.yAxis]) || [],
          itemStyle: {
            color: '#007AFF'
          }
        }]
      }
    
    case 'line':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          data: config.data?.map(item => item[config.xAxis]) || []
        },
        yAxis: {
          type: 'value'
        },
        series: [{
          type: 'line',
          data: config.data?.map(item => item[config.yAxis]) || [],
          smooth: true,
          lineStyle: {
            color: '#34C759'
          },
          itemStyle: {
            color: '#34C759'
          }
        }]
      }
    
    case 'pie':
      return {
        ...baseOption,
        series: [{
          type: 'pie',
          radius: '50%',
          data: config.data?.map(item => ({
            name: item[config.xAxis],
            value: item[config.yAxis]
          })) || [],
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        }]
      }
    
    default:
      return {
        ...baseOption,
        title: {
          text: '不支持的图表类型',
          left: 'center',
          top: '50%',
          textStyle: {
            color: '#999'
          }
        }
      }
  }
}

const send = async () => {
  const q = question.value.trim()
  if (!q || sending.value) return
  
  // 如果没有会话ID，生成一个新的
  if (!sessionId.value) {
    generateSessionId()
  }
  
  // 添加用户消息
  messages.value.push({
    type: 'user',
    content: q
  })

  // 滚动到最新消息
  scrollToBottom()

  // 添加AI消息占位符（只显示小点点）
  const aiMessageIndex = messages.value.length
  messages.value.push({
    type: 'ai',
    content: '',
    loading: true,
    chartWaiting: false,
    chartConfig: null
  })

  // 滚动到最新消息
  scrollToBottom()

  // 清空输入框和重置状态
  question.value = ''
  sending.value = true
  
  // 使用清理函数重置状态
  clearStates()

  try {
    const response = await fetch('http://localhost:8080/api/ai/bi/query-stream', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        query: q,
        sessionId: sessionId.value,
        timeRange: timeRange.value,
        chartType: chartType.value,
        maxRecords: maxRecords.value,
        includeSql: includeSql.value,
        includeSummary: includeSummary.value
      })
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const reader = response.body.getReader()
    const decoder = new TextDecoder()
    let buffer = ''
    let currentEvent = null

    while (true) {
      const { done, value } = await reader.read()
      
      if (done) break
      
      // 解码并添加到缓冲区
      buffer += decoder.decode(value, { stream: true })
      
      // 按行分割并处理
      const lines = buffer.split('\n')
      
      // 保留最后一行（可能不完整）
      buffer = lines.pop() || ''
      
      for (const line of lines) {
        const trimmedLine = line.trim()
        if (!trimmedLine) continue
        
        if (trimmedLine.startsWith('event:')) {
          const eventType = trimmedLine.substring(6).trim()
          currentEvent = eventType
          
          // 记录事件到流式数据
          streamData.value.push({
            timestamp: new Date().toLocaleTimeString(),
            event: `event: ${eventType}`,
            data: ''
          })
          
          // 根据事件类型更新进度信息
          updateProgress(eventType)
          
          // 设置图表等待状态
          if (eventType === 'chart_generation') {
            messages.value[aiMessageIndex].chartWaiting = true
            console.log('开始等待图表数据...')
          }
          
        } else if (trimmedLine.startsWith('data:')) {
          const dataContent = trimmedLine.substring(5).trim()
          if (!dataContent) continue
          
          // 记录数据到流式数据
          if (streamData.value.length > 0) {
            streamData.value[streamData.value.length - 1].data = dataContent
          }
          
          // 根据事件类型处理数据
          if (currentEvent === 'summary_ready') {
            console.log('收到总结数据块:', dataContent)
            console.log('当前时间:', new Date().toLocaleTimeString())
            console.log('数据块长度:', dataContent.length)
            
            // 真正的分块流式显示 - 每个数据块立即显示
            if (messages.value[aiMessageIndex].content) {
              messages.value[aiMessageIndex].content += '\n' + dataContent
            } else {
              messages.value[aiMessageIndex].content = dataContent
            }
            
            console.log('AI消息内容已更新，当前长度:', messages.value[aiMessageIndex].content.length)
            
            // 强制更新视图
            messages.value = [...messages.value]
            
            // 立即滚动到底部
            scrollToBottom()
            
            // 隐藏小点点，显示进度
            messages.value[aiMessageIndex].loading = false
          } else if (currentEvent === 'chart_ready') {
            try {
              console.log('收到图表配置数据:', dataContent)
              const parsedConfig = JSON.parse(dataContent)
              console.log('解析后的图表配置:', parsedConfig)
              
              // 等待总结完全显示后再显示图表
              setTimeout(() => {
                // 更新对应消息的图表配置
                messages.value[aiMessageIndex].chartConfig = parsedConfig
                messages.value[aiMessageIndex].chartWaiting = false
                
                // 图表数据完整，可以开始渲染
                nextTick(() => {
                  console.log('准备渲染图表，配置:', parsedConfig)
                  renderChartForMessage(parsedConfig, aiMessageIndex)
                  // 滚动到最新消息
                  scrollToBottom()
                })
              }, 1000) // 等待1秒，确保总结完全显示
              
            } catch (parseError) {
              console.error('解析图表配置失败:', parseError)
              console.error('原始数据:', dataContent)
            }
          } else if (currentEvent === 'chart_skipped') {
            try {
              const skipInfo = JSON.parse(dataContent)
              console.log('图表生成被跳过:', skipInfo)
              
              // 更新对应消息的图表配置
              messages.value[aiMessageIndex].chartConfig = {
                type: 'skipped',
                title: '图表生成被跳过',
                reason: skipInfo.reason,
                analysis: skipInfo.analysis,
                questionType: skipInfo.questionType
              }
              messages.value[aiMessageIndex].chartWaiting = false
              
              // 渲染跳过的图表
              nextTick(() => {
                console.log('准备渲染跳过的图表:', messages.value[aiMessageIndex].chartConfig)
                renderChartForMessage(messages.value[aiMessageIndex].chartConfig, aiMessageIndex)
              })
            } catch (parseError) {
              console.error('解析跳过信息失败:', parseError)
            }
          } else if (currentEvent === 'complete') {
            // 流式结束，隐藏进度区域
            console.log('流式数据接收完成')
            sending.value = false
            conversationComplete.value = true // 设置对话完成状态
            
            // 如果还有图表等待渲染，再次尝试
            if (messages.value[aiMessageIndex].chartConfig && !messages.value[aiMessageIndex].chartWaiting) {
              console.log('流式结束后再次尝试渲染图表')
              nextTick(() => {
                renderChartForMessage(messages.value[aiMessageIndex].chartConfig, aiMessageIndex)
              })
            }
            
            // 强制检查图表状态并渲染
            setTimeout(() => {
              console.log('延迟检查图表状态:', messages.value[aiMessageIndex].chartConfig)
              if (messages.value[aiMessageIndex].chartConfig) {
                console.log('延迟渲染图表')
                // 确保图表实例存在
                if (!chartInstance) {
                  // 这里不需要初始化，因为每个消息都有自己的图表实例
                }
                renderChartForMessage(messages.value[aiMessageIndex].chartConfig, aiMessageIndex)
              }
            }, 200)
            
            return
          }
        }
      }
    }
    
  } catch (error) {
    console.error('发送消息失败:', error)
    messages.value[aiMessageIndex].content = '发送失败：' + error.message
    messages.value[aiMessageIndex].loading = false
    sending.value = false
  }
}
</script>

<style scoped>
/* 模态框整体样式 */
.bi-modal-dialog :deep(.el-dialog) {
  max-width: 90vw;
  max-height: 90vh;
  margin-top: 2vh !important;
  margin-bottom: 8vh !important;
}

/* 强制覆盖Element Plus的默认样式 */
.bi-modal-dialog :deep(.el-dialog__wrapper) {
  padding-top: 2vh !important;
}

.bi-modal-dialog :deep(.el-dialog) {
  position: relative !important;
  top: 0 !important;
  transform: none !important;
  margin: 2vh auto 8vh auto !important;
}

/* 自定义类名样式 */
:deep(.bi-modal-custom) {
  margin-top: 2vh !important;
  margin-bottom: 8vh !important;
}

:deep(.bi-modal-custom .el-dialog__wrapper) {
  padding-top: 2vh !important;
}

.bi-modal-content {
  display: flex;
  flex-direction: column;
  height: 90vh;
  min-height: 650px;
  max-height: 90vh;
}

/* 聊天容器 */
.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.chat-header {
  padding: 12px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 8px 8px 0 0;
  text-align: center;
}

.chat-header h2 {
  margin: 0 0 4px 0;
  font-size: 18px;
  font-weight: 600;
}

.chat-header p {
  margin: 0;
  opacity: 0.9;
  font-size: 12px;
}

/* 消息区域 */
.messages-area {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: #f8f9fa;
  position: relative;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: #6c757d;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.empty-text {
  font-size: 18px;
  margin-bottom: 8px;
  font-weight: 500;
}

.empty-example {
  font-size: 14px;
  opacity: 0.7;
}

/* 消息列表 */
.messages-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.message {
  display: flex;
  flex-direction: column;
}

/* 消息内容布局 */
.message-content {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  max-width: 80%;
  --avatar-size: 40px;
  --gap-size: 8px;
  width: 100%;
  position: relative;
}

.user-message {
  align-self: flex-end;
  flex-direction: row;
  justify-content: flex-end;
}

.user-message .message-bubble {
  order: 1;
  flex: 0 1 auto;
  margin-right: 8px;
  max-width: 70%;
}

.user-message .message-avatar {
  order: 2;
  flex-shrink: 0;
}

.ai-message {
  align-self: flex-start;
  flex-direction: row;
}

.ai-message .message-avatar {
  order: 1;
  flex-shrink: 0;
}

.ai-message .message-bubble {
  order: 2;
  flex: 0 1 auto;
  margin-left: 8px;
  max-width: 70%;
}

/* 头像 */
.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}

.user-avatar {
  background: #007bff;
  color: white;
}

.ai-avatar {
  background: #28a745;
  color: white;
}

/* 消息气泡 */
.message-bubble {
  padding: 16px;
  border-radius: 18px;
  max-width: 100%;
  word-wrap: break-word;
  line-height: 1.5;
}

.user-bubble {
  background: #007bff;
  color: white;
  border-bottom-right-radius: 6px;
}

.ai-bubble {
  background: white;
  color: #333;
  border: 1px solid #e9ecef;
  border-bottom-left-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 加载动画 */
.loading-dots {
  display: flex;
  gap: 4px;
  align-items: center;
  font-size: 18px;
  color: #6c757d;
}

.loading-dots::after {
  content: '';
  width: 4px;
  height: 4px;
  background: #6c757d;
  border-radius: 50%;
  animation: loading 1.4s infinite ease-in-out;
}

@keyframes loading {
  0%, 80%, 100% {
    transform: scale(0);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* 图表等待区域 */
.chart-waiting {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
  margin-top: 12px;
  border: 1px dashed #dee2e6;
}

.waiting-icon {
  font-size: 20px;
}

.waiting-text {
  color: #6c757d;
  font-size: 14px;
}

/* 图表区域 */
.chart-area {
  margin-top: 16px;
  border-top: 1px solid #e9ecef;
  padding-top: 16px;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.chart-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #495057;
}

.chart-status {
  display: flex;
  gap: 8px;
}

.status-waiting {
  color: #ffc107;
  font-size: 12px;
  font-weight: 500;
}

.status-skipped {
  color: #6c757d;
  font-size: 12px;
  font-weight: 500;
}

.status-ready {
  color: #28a745;
  font-size: 12px;
  font-weight: 500;
}

.chart-container {
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e9ecef;
  overflow: hidden;
  position: relative;
  min-height: 300px;
}

.chart-renderer {
  width: 100% !important;
  height: 100% !important;
  min-height: 300px;
}

.chart-raw-data {
  margin-top: 12px;
}

.chart-raw-data summary {
  cursor: pointer;
  color: #6c757d;
  font-size: 12px;
  user-select: none;
}

.chart-raw-data pre {
  background: #f8f9fa;
  padding: 8px;
  border-radius: 4px;
  font-size: 11px;
  overflow-x: auto;
  margin: 8px 0 0 0;
}

/* 进度区域 */
.progress-area {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

.progress-bubble {
  background: white;
  border: 1px solid #e9ecef;
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  max-width: 500px;
  width: 100%;
}

.progress-title {
  font-weight: 600;
  color: #495057;
  margin-bottom: 12px;
  text-align: center;
}

.progress-list {
  max-height: 200px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.progress-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  background: #f8f9fa;
  border-radius: 6px;
  font-size: 14px;
}

.progress-icon {
  font-size: 16px;
}

.progress-text {
  color: #495057;
}

/* 输入区域 */
.input-area {
  background: white;
  border-top: 1px solid #e9ecef;
  padding: 20px 0 0 0;
  border-radius: 0 0 8px 8px;
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.input-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.input-options {
  display: flex;
  gap: 12px;
  align-items: center;
}

.input-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.input-help {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #6c757d;
}

.input-help-text {
  margin-right: 10px;
  color: #a0aec0;
  font-size: 12px;
}

.session-info {
  color: #007bff;
  font-weight: 500;
}

/* 滚动条样式 */
.messages-area::-webkit-scrollbar {
  width: 6px;
}

.messages-area::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.messages-area::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.messages-area::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.progress-list::-webkit-scrollbar {
  width: 4px;
}

.progress-list::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 2px;
}

.progress-list::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 2px;
}

.progress-list::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>
